<template>
  <div class="role-manage">
    <!-- 查询区域 -->
    <div class="query-form">
      <el-form :inline="true" :model="queryForm" ref="refQueryForm">
        <el-form-item label="角色名称:" prop="roleName">
          <el-input v-model="queryForm.roleName" placeholder="请输入角色名称"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="queryFormSubmit" v-auth="'role-query'">查询</el-button>
          <el-button @click="restForm('refQueryForm')">重置</el-button>
        </el-form-item>
      </el-form>
    </div>
    <!-- 表格 -->
    <div class="base-table">
      <!-- 表格头部操作区 -->
      <div class="action" v-auth="'role-add'">
        <el-button type="primary" @click="addRole()">创建角色</el-button>
      </div>
      <!-- 用户列表 -->
      <el-table :data="roleList">
        <el-table-column
          v-for="colum in colums"
          :key="colum.prop"
          :prop="colum.prop"
          :label="colum.label"
          :formatter="colum.formatter"
          :width="colum.width"
        >
        </el-table-column>
        <el-table-column label="操作" width="260">
          <template #default="scope">
            <el-button size="mini" @click="editRole(scope.row)" v-auth="'role-edit'">编辑</el-button>
            <el-button type="primary" size="mini" @click="editRolePermission(scope.row)" v-auth="'role-edit'">设置权限</el-button>
            <el-button type="danger" size="mini" @click="deleteRole(scope.row)" v-auth="'role-delete'">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        class="pagination"
        background
        layout="prev, pager, next"
        :total="pager.total"
        :page-size="pager.pageSize"
        @current-change="handlePageNumChange"
      />
    </div>
    <!-- 新增角色弹窗 -->
    <el-dialog :title="action === 'add' ? '新增角色' : '编辑角色'" v-model="showModal" @close="roleModelClose">
      <el-form :model="roleForm" ref="refRoleForm" label-width="100px" :rules="rules">
        <el-form-item label="角色名称" prop="roleName">
          <el-input v-model="roleForm.roleName" placeholder="请输入角色名称" />
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input type="textarea" :rows="3" v-model="roleForm.remark" placeholder="请输入备注" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span>
          <el-button @click="roleModelClose">取 消</el-button>
          <el-button type="primary" @click="roleModelSubmit">确 定</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 权限弹框 -->
    <el-dialog title="权限设置" v-model="showPermission" @close="closePermissionModel">
      <el-form label-width="100px">
        <el-form-item label="角色名称">
          {{ curRoleName }}
        </el-form-item>
        <el-form-item label="选择权限">
          <el-tree ref="permissionTree" :data="menuList" show-checkbox node-key="_id" default-expand-all :props="{ label: 'menuName' }"> </el-tree>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="closePermissionModel">取 消</el-button>
          <el-button type="primary" @click="permissionModelSubmit">确 定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>
<script>
import { mapState } from 'vuex';
import utils from '@/utils/utils.js';
export default {
  name: 'Role',
  computed: {
    ...mapState(['menuList']),
  },
  data() {
    return {
      // 查询表单
      queryForm: { roleName: '' },
      // 角色表单
      roleForm: { remark: '', roleName: '' },
      // 展示的 角色列表，默认和roleList 一致，只有条件查询的时候才修改
      roleList: [],
      // 角色表单 校验规则
      rules: { roleName: [{ required: true, message: '请输入角色名称' }], remark: [{ required: true, message: '请输入备注' }] },
      // 弹框显示
      showModal: false,
      // 表单的类型   add   edit  delete
      action: 'add',
      // 角色表格列选项
      colums: [
        { label: '角色名称', prop: 'roleName' },
        { label: '备注', prop: 'remark' },
        {
          label: '权限列表',
          prop: 'permissionList',
          width: 200,
          formatter: (row, column, value) => {
            let list = value.halfCheckedKeys || [];
            return list
              .filter((key) => this.actionMap[key])
              .map((key) => this.actionMap[key])
              .join(',');
          },
        },
        {
          label: '创建时间',
          prop: 'createTime',
          width: 150,
          formatter(row, column, value) {
            return utils.formateDate(new Date(value));
          },
        },
        {
          label: '更新时间',
          prop: 'updateTime',
          width: 150,
          formatter(row, column, value) {
            return utils.formateDate(new Date(value));
          },
        },
      ],
      // 分页
      pager: { total: 0, pageSize: 10, pageNum: 1 },
      // 权限展示
      showPermission: false,
      curRoleId: '',
      curRoleName: '',
      // 菜单映射表  key是id  value是menuName
      actionMap: {},
    };
  },
  mounted() {
    this.getRoleList();
    this.getActionMap();
  },
  methods: {
    async getRoleList() {
      let { list, page } = await this.$api.getRoleList({ ...this.queryForm, ...this.pager });
      this.roleList = list;
      this.pager = page;
    },
    // 查询表单提交事件
    queryFormSubmit() {
      this.getRoleList();
    },
    // 添加 角色
    addRole() {
      this.action = 'add';
      this.showModal = true;
    },
    // 修改 角色
    editRole(row) {
      this.action = 'edit';
      this.showModal = true;
      // 在dom更新过后下一个阶段，下一次更新才获取值
      this.$nextTick(() => {
        this.roleForm = { remark: row.remark, _id: row._id, roleName: row.roleName };
        // Object.assign(this.roleForm, row);
      });
    },
    // 修改 角色 权限
    editRolePermission(row) {
      this.showPermission = true;
      this.curRoleId = row._id;
      this.curRoleName = row.roleName;
      let { checkedKeys } = row.permissionList;
      setTimeout(() => {
        this.$refs.permissionTree.setCheckedKeys(checkedKeys);
      });
    },
    // 删除 角色
    async deleteRole({ _id }) {
      await this.$api.roleSubmit({ _id, action: 'delete' });
      this.$message.success('删除成功');
      this.getRoleList();
    },
    // 弹窗关闭事件
    roleModelClose() {
      this.showModal = false;
      this.restForm('refRoleForm');
    },
    // 弹窗提交事件
    roleModelSubmit() {
      this.$refs.refRoleForm.validate(async (valid) => {
        if (valid) {
          let { action, roleForm } = this;
          let param = { ...roleForm, action };
          let res = await this.$api.roleSubmit(param);
          this.showModal = false;
          this.restForm('refRoleForm');
          this.$message.success(`角色${this.action == 'add' ? '添加' : '编辑'}成功`);
          this.getRoleList();
        }
      });
    },
    // 重置表单
    restForm(formName) {
      this.$refs[formName].resetFields();
    },
    // 分页事件处理
    handlePageNumChange(pageNum) {
      this.pager.pageNum = pageNum;
      this.getRoleList();
    },
    closePermissionModel() {
      this.showPermission = false;
    },
    async permissionModelSubmit() {
      // 选中节点
      let nodes = this.$refs.permissionTree.getCheckedNodes();
      // 半选节点
      let halfKeys = this.$refs.permissionTree.getHalfCheckedKeys();
      // 获取半选节点是为了防止添加节点的时候按钮权限是全选的就把这个新添加的按钮也选上了
      // 最后一级
      let checkedKeys = [];
      // 有子节点的节点
      let parentKeys = [];
      nodes.map((node) => {
        if (!node.children) checkedKeys.push(node._id);
        else parentKeys.push(node._id);
      });
      let params = { _id: this.curRoleId, permissionList: { checkedKeys, halfCheckedKeys: parentKeys.concat(halfKeys) } };
      await this.$api.roleUpdatePermission(params);
      this.showPermission = false;
      this.$message.success('设置成功');
      this.getRoleList();
    },
    getActionMap() {
      let list = this.menuList;
      let actionMap = {};
      const deepAction = (arr) => {
        while (arr.length) {
          let item = arr.pop();
          if (item.children && item.action) {
            actionMap[item._id] = item.menuName;
          }
          if (item.children && !item.action) {
            deepAction(item.children);
          }
        }
      };
      deepAction(JSON.parse(JSON.stringify(list)));
      this.actionMap = actionMap;
    },
  },
};
</script>
<style lang="scss"></style>
